package com.mdb.open.trade.facade.trade;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mdb.bc.api.data.ResultEx;
import com.mdb.enums.PlatformRetCodeEnum;
import com.mdb.open.common.enums.trade.status.*;
import com.mdb.open.common.enums.trade.type.ClaimTypeEnum;
import com.mdb.open.trade.config.AccountingDateUtil;
import com.mdb.open.trade.domain.bo.trade.GetInwardRemitBo;
import com.mdb.open.trade.domain.bo.trade.ProcessInwardClaimBo;
import com.mdb.open.trade.domain.bo.trade.SaveInwardClaimBo;
import com.mdb.open.trade.domain.bo.trade.UpdateInwardRemitBo;
import com.mdb.open.trade.domain.dto.trade.ClaimItemDto;
import com.mdb.open.trade.domain.po.trade.InwardClaim;
import com.mdb.open.trade.domain.po.trade.InwardRemittance;
import com.mdb.open.trade.rabbit.model.InwardClaimProcessMo;
import com.mdb.open.trade.rabbit.provider.InwardClaimProcessProvider;
import com.mdb.open.trade.service.trade.*;
import com.mdb.open.trade.utils.NumUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * @description:
 * @author: you.yichao
 * @create: 2019-07-13 10:50
 **/

@Service
public class InwardClaimFacade {

    @Autowired
    TfInwardRemittanceService tfInwardRemittanceService;

    @Autowired
    TfInwardClaimService tfInwardClaimService;

    @Autowired
    InwardClaimProcessProvider inwardClaimProcessProvider;


    @Autowired
    TfLoanApplyBaseInfoService tfLoanApplyBaseInfoService;

    @Autowired
    TfTradeFileBasicInfoService tfTradeFileBasicInfoService;

    @Autowired
    TfLoanContractService tfLoanContractService;

    @Autowired
    TfLoanProcessLogService tfLoanProcessLogService;

    @Autowired
    TfCusAccService tfCusAccService;

    @Autowired
    AccountingDateUtil accountingDateUtil;

    @Transactional
    public ResultEx claimSolve(ProcessInwardClaimBo dto) {

        GetInwardRemitBo bo = new GetInwardRemitBo();
        bo.setRemitNo(dto.getRemitNo());
        bo.setCustomerCode(dto.getCustomerCode());
        bo.setStatus(InwardRemitStatusEnum.UN_CLAIMED);


        ResultEx<InwardRemittance> inwardEx = tfInwardRemittanceService.getInwardRemitByNo(bo);
        if (inwardEx.isFailed()) {
            return ResultEx.fail("未找到汇入记录");
        }
        InwardRemittance remittance = inwardEx.getData();
        LocalDateTime now = accountingDateUtil.getAccountingDateTime();

        if (!InwardProdRemitStatusEnum.NORMAL.equals(remittance.getProdStatus())
                || !InwardMerRemitStatusEnum.NORMAL.equals(remittance.getMerStatus())
                || !InwardRemitCreditStatusEnum.ALREADY_ACCOUNTED.equals(remittance.getCreditStatus())) {
            return ResultEx.makeResult(PlatformRetCodeEnum.WAIT_CLAIM_INWARD_RECORD_NOT_EXIST);
        }

        BigDecimal inwardAmount = remittance.getRemitAmount();
        BigDecimal otherAmount = BigDecimal.ZERO;
        List<ClaimItemDto> claimItemDtoList = dto.getClaimItemDtoList();
        List<SaveInwardClaimBo> saveInwardClaimBoList = Lists.newArrayList();
        Map<String, String> uqMap = Maps.newHashMap();
        for (ClaimItemDto itemDto : claimItemDtoList) {
            inwardAmount = inwardAmount.subtract(NumUtils.toBigDecimal(itemDto.getClaimAmount()));
            otherAmount = inwardAmount;
            if (uqMap.containsKey(itemDto.getBusinessNo())) {
                return ResultEx.fail("业务编号重复");
            }
            uqMap.put(itemDto.getBusinessNo(), itemDto.getBusinessNo());
            SaveInwardClaimBo claimBo = new SaveInwardClaimBo();
            claimBo.setRemitNo(remittance.getRemitNo());
            claimBo.setCustomerCode(remittance.getCustomerCode());
            claimBo.setCustomerName(remittance.getCustomerName());
            claimBo.setMcustomerCode(remittance.getMcustomerCode());
            claimBo.setMerchantNo(remittance.getMerchantNo());
            claimBo.setMerchantName(remittance.getMerchantName());
            claimBo.setBusinessNo(itemDto.getBusinessNo());
            claimBo.setReceiveAcc(remittance.getReceiveAcc());
            claimBo.setClaimAmount(NumUtils.toBigDecimal(itemDto.getClaimAmount()));
            claimBo.setCcy(remittance.getCcy());
            claimBo.setPurposes(itemDto.getPurposes());
            claimBo.setClaimType(ClaimTypeEnum.BUSINESS_CLAIM);
            claimBo.setClaimDate(now);
            claimBo.setStatus(InwardClaimStatusEnum.PROCESSING);
            claimBo.setRepaymentStatus(ClaimRepaymentStatusEnum.JUDGE);
            saveInwardClaimBoList.add(claimBo);

        }

        if (otherAmount.compareTo(BigDecimal.ZERO) != 0) {
            return ResultEx.makeResult(PlatformRetCodeEnum.INWARD_AMOUNT_ILLEGAL);
        }

        // 认领插入
        for (SaveInwardClaimBo claimBo : saveInwardClaimBoList) {
            ResultEx<InwardClaim> ex = tfInwardClaimService.saveInwardClaim(claimBo);
            if (ex.isFailed()) {
                return ex;
            }
        }

        UpdateInwardRemitBo inwardRemitBo = new UpdateInwardRemitBo();
        inwardRemitBo.setCustomerCode(remittance.getCustomerCode());
        inwardRemitBo.setRemitNo(remittance.getRemitNo());
        inwardRemitBo.setStatus(InwardRemitStatusEnum.CLAIMED);
        inwardRemitBo.setOldStatus(InwardRemitStatusEnum.UN_CLAIMED);

        ResultEx inwardRemitEx = tfInwardRemittanceService.updateInwardRemit(inwardRemitBo);
        if (inwardRemitEx.isFailed()) {
            return inwardRemitEx;
        }

        //还款 存款操作
        InwardClaimProcessMo mo = new InwardClaimProcessMo();
        mo.setRemitNo(dto.getRemitNo());
        inwardClaimProcessProvider.send(mo);

        return ResultEx.ok();

    }

}
